package com.jims.master.modules.med.utils;

import com.google.common.collect.Lists;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jims.master.common.web.Dto;
import com.jims.master.common.web.impl.BaseDto;
import org.dom4j.*;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * Created by chenxy on 2017/6/9.
 * ��ȡҽ��com�������
 */
public class MedicalComUtil {
    private static final String XMLPREFER="<?xml version=\"1.0\" encoding=\"utf16\" standalone=\"yes\" ?>";
    private static final String XMLSUFFER="</input></root>";
    private  String targetClass;
    private MedicalComUtil(String targetClass){
      this.targetClass=targetClass;
    }
    private static MedicalComUtil medicalComUtil=null;//

    public static MedicalComUtil newInstance(String targetClass){
         if(medicalComUtil==null){
             medicalComUtil=new MedicalComUtil(targetClass);
         }
        return medicalComUtil;
     }


   // com�������
    private static ActiveXComponent activeXComponent=null;
    private static com.jacob.com.Dispatch dispatch =null;



    /**
     * ��ȡ�������
     * chenxy
     * @return
     */
    public  ActiveXComponent getActiveXComponent(){
        if(activeXComponent==null){
            activeXComponent= new ActiveXComponent(targetClass);
        }
        return activeXComponent;
    }

    /**
     * ��ȡ��ݽṹ����
     * @return
     */
     public Dispatch getDispatch(){
        if(activeXComponent==null){
            return null;
        }else{
            if(dispatch==null){
                 dispatch= (Dispatch)activeXComponent.getObject();
                 return dispatch;
            }else{
                return dispatch;
            }
        }
      }

  //---------����Ϊ�����ӿ��������xml�ļ�---------------------------------------------------------------




    /**
     * @Author ������
     * @desc   �ж�һ���ڵ�����Ƿ�����ӽڵ�
     * @param node  �ڵ����
     * @return  if node �����ӽڵ� �򷵻�true  else return false
     */
    public static boolean isFinalLeaf(Element node){
        List<Element>  elements= Lists.newArrayList();
        for (Iterator it = node.elementIterator(); it.hasNext();) {
             Element leaf = (Element) it.next();
             elements.add(leaf);
        }
        if(elements.size()>0)
            return true;
            return false;
     }

    /**
     * @Author ������
     * @desc  ��һ���ڵ�Ԫ�ص���ƺ����ݷŵ�DTO��
     * @param returnVal ��xml�ڵ���ƺͽڵ����� ѹ����DTO ����
     * @param node xml�ڵ����
     * @return
     */
    public static Dto addData(Dto returnVal,Element node){
        String nodeName=node.getName();//�ڵ����
        Object nodeData=node.getData();//�ڵ�����
        returnVal.put(nodeName,nodeData);
        return returnVal;
    }

    /**
     * @Author ������
     * @desc  �ж����
     * @param node xml�ڵ����
     * @return
     */
    public static boolean judgeIsSuccess(Element node){
        boolean returnVal=false;
        if("state".equalsIgnoreCase(node.getName())){
            Attribute nodeAttr = node.attribute("success");
            returnVal=Boolean.parseBoolean(nodeAttr.getData().toString());
        }
        return returnVal;
    }

    /**
     * @desc ��û���ӽڵ�Ľڵ�����Ժ�����ֵ ����DTo
     * @Author ������
     * @param returnVal  DTo
     * @param node  �ڵ����
     * @return
     */
    public static Dto addAttribute(Dto returnVal,Element node){
         List<Attribute> attributes=node.attributes();
         for (Attribute attribute:attributes){
              String attributeName=node.getName()+"-"+attribute.getName();
              String attributeValue=attribute.getValue();
              String value=returnVal.getAsString(attributeName);
              if(value!=null&&!"".equals(value)){
                  String[] attr=attributeName.split("-");
                  if(attr.length>2){
                      attributeName=attributeName.substring(0,attributeName.indexOf("-"))+(Integer.parseInt(attr[2])+1);
                  }else{
                      attributeName=attributeName+"0";
                  }
                  returnVal.put(attributeName,attributeValue);
              }else{
                  returnVal.put(attributeName,attributeValue);
              }
          }
         return returnVal;
    }



    /**
     * @Author ������
     * @desc  ����ѭ����ڵ��µ��ӽڵ�
     * @param rootNode  ��ڵ����
     * @param returnVal  ����ڵ���ƺͽڵ�  �ڵ����Ժͽڵ�����ֵ
     *                   @<p>
     *                     ֻ�����û���ӽڵ�Ľڵ���ƺͽڵ����� �ڵ����Ժͽڵ�����ֵ
     *                   </p>
     * @return
     */
    public static Dto loopNodes(Element rootNode,Dto returnVal){
        for (Iterator it = rootNode.elementIterator(); it.hasNext();) {
            Element leaf = (Element) it.next();
            if(!isFinalLeaf(leaf)){
                //�������ӽڵ�
                 returnVal=addData(returnVal,leaf);
                 returnVal=addAttribute(returnVal,leaf);
            }else{
                //�ݹ�
                returnVal=loopNodes(leaf,returnVal);
            }
        }
        return returnVal;
    }


    /**
     * �������
     * @Author ������
     * @desc  �������ص�ָ����xml
     * @param outParamsXml  �ӿڵ��õķ���xml�ַ�
     * @return
     * @throws DocumentException
     */
    public static final Dto bjybDto(String outParamsXml) {
        Dto returnVal = new BaseDto();
        try {
            Document document = DocumentHelper.parseText(outParamsXml);
            Element rootNode = document.getRootElement();
            /**
            * 1 ���state�ڵ�
            */
            boolean isSuccess=judgeIsSuccess(rootNode.element("state"));

            /**
             * 2 ��ȡ������ʾ����warnin��information �ӽڵ�����
             */

            /**
             * 3 ����true ������������ ���ҷ��ص��óɹ�
             */
            /**
             * 4 ����false ��ȡ������ʾ����error�ӽڵ�����  ���ص���ʧ��
             */
            returnVal=loopNodes(rootNode,returnVal);
            returnVal.put("isSuccess",isSuccess);
            returnVal=handleData(returnVal);
            return returnVal;
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return returnVal;

    }

    /**
     *@Author ������
      *@desc �������;���ͻ���Ϣ���
     * @param returnVal
     * @return
     */
    public static Dto handleData(Dto returnVal ){
        Set<String> set=returnVal.keySet();
        List<String> errors=Lists.newArrayList();
        List<String> warnings=Lists.newArrayList();
        List<String> informations=Lists.newArrayList();
        for(String key:set){
            if(key.contains("info")){
                if(key.contains("error")){
                    errors.add((String)returnVal.get(key));
                }else if(key.contains("warning")){
                    warnings.add((String)returnVal.get(key));
                }else if(key.contains("information")){
                    informations.add((String)returnVal.get(key));
                }
            }
        }
        returnVal.put("errors",errors);
        returnVal.put("warnings",warnings);
        returnVal.put("informations",informations);
        return returnVal;
    }

    /**
     * ��ݲ�ͬ�Ľӿ���ɲ�ͬ��xml�ļ�
     * @param divideDto  dto ���
     * @param functionName �������
     * @return
     */
    public static String createXMlByDto(Dto divideDto, String functionName) {
        StringBuilder sb=new StringBuilder(XMLPREFER+"<root version=\"2.003\" sender=\"capinfo\"><input>");
        if("Divide".equals(functionName)){
            //���÷ֽ�
            //1 ������Ϣ
            sb.append("<tradeinfo>");
            sb.append("<curetype>"+divideDto.getAsString("curetype")+"</curetype>");
            sb.append("<illtype>"+divideDto.getAsString("illtype")+"</illtype>" +
                    "<feeno></feeno>"+
                    "<operator>"+divideDto.getAsString("operator")+"</operator>");
            sb.append("</tradeinfo>");
            //2������Ϣ�Լ������Ϣ
            sb.append("<recipearray>");
            List<BaseDto> diagnosises=divideDto.getAsList("diagnosises");
            List<BaseDto> recipearray=divideDto.getAsList("recipearray");
            List<BaseDto> feeitemarray=divideDto.getAsList("feeitemarray");
            if(diagnosises!=null&&diagnosises.size()>0){
                    //������ݵ��������xml��ǩ�ĸ���
                   for(BaseDto recipear:recipearray){
                        sb=createRecipearByDto(recipear,sb,diagnosises.get(0));
                   }
            }
            sb.append("</recipearray>");
            //3 ��ϸ��Ϣ
            sb.append("<feeitemarray>");
            for(BaseDto feeitem:feeitemarray){
                sb=createFeeItemByDto(feeitem, sb);
            }
            sb.append("</feeitemarray>");
         }
        sb.append(XMLSUFFER);
        return sb.toString();
    }

    /**
     * ƴ��һ��������ϸ��Ϣxml
     * @param feeitem
     * @param sb
     * @return
     */
    private static StringBuilder createFeeItemByDto(BaseDto feeitem, StringBuilder sb) {
        sb.append("<feeitem " +
                " itemno=\""+feeitem.getAsString("itemno")+"\"" +
                " recipeno=\""+feeitem.getAsString("recipeno")+"\" " +
                " hiscode=\""+feeitem.getAsString("hiscode")+"\" " +
                " itemname=\""+feeitem.getAsString("itemname")+"\"" +
                " itemtype=\""+feeitem.getAsString("itemtype")+"\" " +
                " unitprice=\""+feeitem.getAsString("unitprice")+"\" " +
                " count=\""+feeitem.getAsString("count")+"\"" +
                " fee=\""+feeitem.getAsString("fee")+"\"" +
                " dose=\""+feeitem.getAsString("dose")+"\"" +
                " specification=\""+feeitem.getAsString("specification")+"\"" +
                " unit=\""+feeitem.getAsString("unit")+"\" " +
                " howtouse=\""+feeitem.getAsString("howtouse")+"\" " +
                " dosage=\""+feeitem.getAsString("dosage")+"\"" +
                " packaging=\""+feeitem.getAsString("packaging")+"\"" +
                " minpackage=\""+feeitem.getAsString("minpackage")+"\"" +
                " conversion=\""+feeitem.getAsString("conversion")+"\"" +
                " days=\""+feeitem.getAsString("days")+"\"" +
                " babyflag="+feeitem.getAsString("babyflag")+" " +
                " drugapprovalnumber =\""+feeitem.getAsString("drugapprovalnumber")+"\"/>");
        return sb;
    }

    /**
     * ƴ��һ��������Ϣxml���
     * @param recipear
     * @param sb
     * @return
     */
    private static StringBuilder createRecipearByDto(BaseDto recipear, StringBuilder sb,BaseDto diagones) {
        sb.append("<recipe>");
        sb.append("<diagnoseno name=\"������\">"+diagones.getAsString("diagnoseno")+"</diagnoseno>" +
                "<recipeno name=\"�������\">"+recipear.getAsString("recipeno")+"</recipeno>" +
                "<recipedate name=\"��������ʱ��\">"+recipear.getAsString("recipedate")+"</recipedate>" +
                "<diagnosename name=\"������\">"+diagones.getAsString("diagnosename")+"</diagnosename>" +
                "<diagnosecode name=\"��ϱ���\">"+diagones.getAsString("diagnosecode")+"</diagnosecode>" +
                "<medicalrecord name=\"������Ϣ\"></medicalrecord>" +
                "<sectioncode name=\"����Ʊ����\"></sectioncode> " +
                "<sectionname name=\"����Ʊ����\"></sectionname>" +
                "<hissectionname name=\"his����Ʊ����\"></hissectionname>" +
                "<drid name=\"ҽʦ���\"></drid> " +
                "<drname name=\"ҽʦ����\"></drname> " +
                "<recipetype name=\"�������1��ҽ���ڴ��� 2��ҽ���⴦����\">"+recipear.getAsString("recipetype")+"</recipetype>" +
                " <helpmedicineflag name=����ҩ��ʶ��>"+recipear.getAsString("helpmedicineflag")+"</helpmedicineflag>" +
                "<registertradeno name=\"�ҺŽ�����ˮ��\"></registertradeno>" +
                "<billstype name=\"�������ͣ�1-�Һţ�2-��ҩ���г�ҩ������4-�в�ҩ������5-�������ƣ���\"></billstype>");
        sb.append("</recipe>");
        return sb;
    }




}
